The Node.js® Website
1import { deflateSync } from 'node:zlib';
2
3import provideReleaseData from '@/next-data/providers/releaseData';
4import { VERCEL_REVALIDATE } from '@/next.constants.mjs';
5import { defaultLocale } from '@/next.locales.mjs';
6import type { GitHubApiFile } from '@/types';
7import { getGitHubApiDocsUrl } from '@/util/gitHubUtils';
8import { parseRichTextIntoPlainText } from '@/util/stringUtils';
9
10const getPathnameForApiFile = (name: string, version: string) =>
11 `docs/${version}/api/${name.replace('.md', '.html')}`;
12
13// This is the Route Handler for the `GET` method which handles the request
14// for a digest and metadata of all API pages from the Node.js Website
15// @see https://nextjs.org/docs/app/building-your-application/routing/router-handlers
16export const GET = async () => {
17 const releases = provideReleaseData();
18
19 const { versionWithPrefix } = releases.find(release =>
20 ['Active LTS', 'Maintenance LTS'].includes(release.status)
21 )!;
22
23 const gitHubApiResponse = await fetch(getGitHubApiDocsUrl(versionWithPrefix));
24
25 return gitHubApiResponse.json().then((apiDocsFiles: Array<GitHubApiFile>) => {
26 // maps over each api file and get the download_url, fetch the content and deflates it
27 const mappedApiFiles = apiDocsFiles.map(
28 async ({ name, path: filename, download_url }) => {
29 const apiFileResponse = await fetch(download_url);
30
31 // Retrieves the content as a raw text string
32 const source = await apiFileResponse.text();
33
34 // Removes empty/blank lines or lines just with spaces and trims each line
35 // from leading and trailing paddings/spaces
36 const cleanedContent = parseRichTextIntoPlainText(source);
37
38 const deflatedSource = deflateSync(cleanedContent).toString('base64');
39
40 return {
41 filename,
42 pathname: getPathnameForApiFile(name, versionWithPrefix),
43 content: deflatedSource,
44 };
45 }
46 );
47
48 return Promise.all(mappedApiFiles).then(Response.json);
49 });
50};
51
52// This function generates the static paths that come from the dynamic segments
53// `[locale]/next-data/api-data/` and returns an array of all available static paths
54// This is used for ISR static validation and generation
55export const generateStaticParams = async () => [
56 { locale: defaultLocale.code },
57];
58
59// Enforces that only the paths from `generateStaticParams` are allowed, giving 404 on the contrary
60// @see https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamicparams
61export const dynamicParams = false;
62
63// Enforces that this route is used as static rendering
64// @see https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamic
65export const dynamic = 'error';
66
67// Ensures that this endpoint is invalidated and re-executed every X minutes
68// so that when new deployments happen, the data is refreshed
69// @see https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#revalidate
70export const revalidate = VERCEL_REVALIDATE;